package com.sharp.authorization.service.login.impl;

import com.sharp.authorization.constants.param.AccountParam;
import com.sharp.authorization.constants.token.ChangePasswordTokenItemConst;
import com.sharp.authorization.dao.common.entity.AcUser;
import com.sharp.authorization.dao.common.repository.AcUserService;
import com.sharp.authorization.service.login.ChangePasswordService;
import com.sharp.authorization.service.token.TokenService;
import com.sharp.email.service.EmailService;
import com.sharp.kernel.constant.CommonConst;
import com.sharp.kernel.constant.err.ErrCodeSys;
import com.sharp.framework.service.cache.FrameCacheService;
import com.sharp.framework.utils.security.MD5Util;
import com.sharp.kernel.validate.Validator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;

/**
 * Title: ChangePasswordServiceImpl
 * Description: Copyright: Copyright (c) 2019 Company: BHFAE
 *
 * @author Sharp
 * @date 2020/4/18 15:18
 * @description Project Name: Mall
 * @Package: com.srct.service.account.service.login.impl
 */
@Service
public class ChangePasswordServiceImpl implements ChangePasswordService {
    @Resource
    private TokenService tokenService;
    @Resource
    private FrameCacheService frameCacheService;
    @Resource
    private EmailService emailService;
    @Resource
    private AcUserService acUserService;

    @Override
    public void changePasswordByMsgCode(String phoneNumber, String password) {
        AcUser user = acUserService.getUserByPhoneNumber(phoneNumber);
        Validator.assertNotNull(user, ErrCodeSys.PA_DATA_NOT_EXIST, "用户");
        Validator.assertTrue(StringUtils.equals(user.getPhone(), phoneNumber), ErrCodeSys.PA_DATA_DIFF, "登录用户手机号码");
        changePassword(user, password);
    }

    private void changePassword(AcUser user, String password) {
        if (StringUtils.isNotBlank(user.getPassword())) {
            if (MD5Util.verify(password, user.getPassword())) {
                Validator.assertException(ErrCodeSys.SYS_ERR_MSG, "新老密码相同");
            }
        } else {
            user.setPassword(MD5Util.generate(password));
            user.setPasswordErrorLastTime(null);
            user.setPasswordErrorTimes(0);
            user.setStatus(CommonConst.YES);
            user.setPasswordUpdateLastTime(new Date());
            acUserService.updateByPrimaryKeySelective(user);
        }
    }

    @Override
    public void emailChangeReq(String userId, String email) {
        AcUser user = acUserService.getUserByLoginId(userId);
        Validator.assertNotNull(user, ErrCodeSys.PA_DATA_NOT_EXIST, "用户");
        Validator.assertTrue(StringUtils.equals(user.getEmail(), email), ErrCodeSys.PA_DATA_DIFF, "登录用户邮箱");
        sendChangePasswordEmail(userId, email);
    }

    @Override
    public void sendChangePasswordEmail(String userId, String email) {
        String token = tokenService.buildEmailToken(userId);
        fillChangePasswordToken(userId, email, token);
        sendEmail(userId, email, token);
    }

    private void fillChangePasswordToken(String userId, String email, String token) {
        AcUser user = acUserService.getUserByLoginId(userId);
        Map<String, Object> map = tokenService.getTokenValue(token);
        map.put(ChangePasswordTokenItemConst.USER_ID.name(), userId);
        map.put(ChangePasswordTokenItemConst.EMAIL.name(), email);
        map.put(ChangePasswordTokenItemConst.INIT.name(), user == null);
        tokenService.setTokenValue(token, map);
    }

    private void sendEmail(String id, String email, String token) {
        String title = frameCacheService.getParamValueAvail(AccountParam.EMAIL_SET_PWD_TITLE);
        String textFormat = frameCacheService.getParamValueAvail(AccountParam.EMAIL_SET_PWD_TEXT_FORMAT);
        String confirmUrlFormat = frameCacheService.getParamValueAvail(AccountParam.EMAIL_SET_PWD_CONFIRM_URL);
        String url = String.format(confirmUrlFormat, id, token);
        String text = String.format(textFormat, url);
        emailService.sendEmail(email, title, text);
    }

    @Override
    public void changePassword(String userId, String password) {
        AcUser user = acUserService.getUserByLoginId(userId);
        changePassword(user, password);
    }
}
